//-----------------------------------------------------------------------
// <copyright file="TaskExecutor.cs" 
//        company="MicroMan6502">
//
//    Copyright (c)2010 MicroMan6502. All rights reserved.
//
// </copyright>
//-----------------------------------------------------------------------

namespace EasyThreading
{
    using System;

    /// <summary>
    /// Implements a game service that allows tasks to be queued and executed
    /// on another thread.
    /// </summary>
    public sealed class TaskExecutor : ITaskExecutor, IDisposable
    {
        /// <summary>
        /// The default processor affinity for XBox.
        /// </summary>
        private const int DefaultProcessorAffinity = 4;

        /// <summary>
        /// Holds a reference to the task queue.
        /// </summary>
        private TaskQueue taskQueue;

        /// <summary>
        /// Holds a reference to the threading class.
        /// </summary>
        private TaskThread taskThread;

        /// <summary>
        /// Instantiates a new instance of the TaskExecutor class.
        /// </summary>
        /// <param name="bufferLength">The max task queue length.</param>
        public TaskExecutor(int bufferLength) :
            this(bufferLength, TaskExecutor.DefaultProcessorAffinity)
        {
        }

        /// <summary>
        /// Instantiates a new instance of the TaskExecutor class.
        /// </summary>
        /// <param name="bufferLength">The max task queue length.</param>
        public TaskExecutor(int bufferLength, int processorAffinity)
        {
            this.taskQueue = new TaskQueue(bufferLength);
            this.taskThread = new TaskThread(this.taskQueue, processorAffinity);
        }

        /// <summary>
        /// Gets the number of pending tasks.
        /// </summary>
        public int PendingTaskCount
        {
            get { return this.taskQueue.UnprocessedItemsCount; }
        }

        /// <summary>
        /// Queues a task ready for processing.
        /// </summary>
        /// <param name="task">A reference to the callback.</param>
        /// <param name="param">An optional parameter.</param>
        public void QueueTask(TaskCallback task, object param)
        {
            // add the call back item to the queue
            this.taskQueue.PushItem(task, param);
        }

        /// <summary>
        /// Called to dispose of any system resources.
        /// </summary>
        public void Dispose()
        {
            // dispose the queue
            if (this.taskQueue != null)
            {
                this.taskQueue.Dispose();
            }

            // dispose the thread
            if (this.taskThread != null)
            {
                this.taskThread.Dispose();
            }
        }
    }
}
